# -*- coding: utf-8 -*-

import sys
import os
import logging
from SceneCheckTool.checkScript.CheckBase import CheckBase

try:
    import maya.cmds as cmds
    import pymel.core as pm
    import jarryLibs.mayakit.MayaUtils as mu
    reload(mu)
except:
    pass

logging.basicConfig()
log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)


class ModGroupHierarchyCheck(CheckBase):
    def __init__(self):
        super(ModGroupHierarchyCheck, self).__init__()
        pass

    def init_file(self):
        # import elsLibs.AssetInfoFromFile as elsaif
        # reload(elsaif)
        import elsLibs.Asset as ast

        current_file = mu.sceneName()
        # aif = elsaif.AssetInfoFromFile(current_file)
        # self.asset_name = aif.get_name
        # self.shortType = aif.get_shortType
        # self.step = aif.get_step
        # self.version = aif.get_version
        # self.latest_version_file = aif.get_publish_latest_file("mod")
        # self.latest_version = aif.get_latest_version

        _asset = ast.Asset(current_file)
        current_step = _asset.step
        self.asset_name = _asset.name
        self.shortType = _asset.stype
        self.step = current_step.name
        mod_step = _asset.set_step('mod')
        self.latest_version_file = mod_step.publish_latest_version_file
        self.latest_version = mod_step.publish_latest_version


    def import_mod_ref_file(self):
        if self.latest_version_file:
            latest_abc_file = self.latest_version_file.rsplit(".", 1)[0] + ".abc"
            latest_abc_file = latest_abc_file.replace("\\", "/")
            if latest_abc_file in cmds.file(q=1, reference=1):
                # cmds.file(latest_abc_file, lr=1)
                return latest_abc_file
            if os.path.exists(latest_abc_file):
                namespace = os.path.basename(latest_abc_file).rsplit(".", 1)[0]
                cmds.file(latest_abc_file, reference=1, ignoreVersion=True, mergeNamespacesOnClash=False, gl=True, namespace=namespace)
                return latest_abc_file

    def is_shape_translform(self, node):
        children = cmds.listRelatives(node, c=1, f=1)
        if not children:
            return False
        for i in children:
            if i == node + "|" + node.rsplit("|", 1)[-1] + "Shape":
                return True
        return False

    def check_attr(self, node, target):
        attr_list = ['.uvs', '.modVer', '.topo', '.name']
        for attr in attr_list:
            source_info = cmds.getAttr(node + attr)
            target_info = cmds.getAttr(target + attr)
            if source_info != target_info:
                return False, attr
        return True, True

    def get_short_name(self, node):
        obj = cmds.ls(node, sn=1)
        if obj:
            return obj[0]

    def match_group_hierarchy(self, source_group, target_group, source_parent=None, target_parent=None):
        tracker_grp = "{0}_{1}_tracker_grp".format(self.shortType, self.asset_name)
        ref_namespace = target_group.split("|", 1)[0].split(":", 1)[0]
        ref_tracker_grp = ref_namespace + ":" + tracker_grp
        source_group_short_name = source_group.rsplit("|", 1)[-1]
        target_group_short_name = target_group.rsplit("|", 1)[-1]
        if source_parent:
            source_parent_short_name = source_parent.rsplit("|", 1)[-1]
        if target_parent:
            target_parent_short_name = target_parent.rsplit("|", 1)[-1]
        if not source_group and not target_group:
            return False
        elif source_group and target_group:
            source_name = source_group.rsplit("|", 1)[-1]
            source_name = source_name.rsplit(":", 1)[-1]
            target_name = target_group.rsplit("|", 1)[-1]
            target_name = target_name.rsplit(":", 1)[-1]
            if source_name != target_name:
                print(u"{0} 和 {1} 名称不匹配！".format(source_group, target_group))
                return [source_group_short_name, target_group_short_name]
            else:
                # Skip shape nodes check
                if self.is_shape_translform(source_group) and self.is_shape_translform(target_group):
                    check_attr, attr = self.check_attr(source_group, target_group)
                    if not check_attr:
                        print(u"0. {0} 和 {1} {2}校验属性不一致！".format(source_group_short_name, target_group_short_name, attr))
                        return [source_group_short_name, target_group_short_name]
                    return False
                source_children = cmds.listRelatives(source_group, f=1, c=1)
                target_children = cmds.listRelatives(target_group, f=1, c=1)
                source_short_children = self.get_children_with_short(source_group)
                target_short_children = self.get_children_with_short(target_group)
                if tracker_grp in source_short_children:
                    source_short_children.remove(tracker_grp)
                if ref_tracker_grp in target_short_children:
                    target_short_children.remove(ref_tracker_grp)

                # print source_short_children
                # print target_short_children
                # if source_short_children == target_short_children == []:
                #     return False
                value = (source_short_children and not target_short_children) or (not source_short_children and target_short_children)
                if not value:
                    return False
                # Return if children are different
                if (source_short_children and not target_short_children) or (not source_short_children and target_short_children):
                    print(u"1.{0} 和 {1} 子层级数量不匹配！".format(source_group, target_group))
                    return [self.get_short_name(source_group), self.get_short_name(target_group)]
                elif not source_short_children and not target_short_children:
                    return False
                self.remove_uncheck_group(tracker_grp, source_children, target_children, source_short_children, target_short_children)
                if len(source_short_children) != len(target_short_children):
                    print(u"2.{0} 和 {1} 子层级数量不匹配！".format(source_group, target_group))
                    return [source_group_short_name, target_group_short_name]
                if not self.check_children_sequence(source_short_children, target_short_children):
                    print(u"3.{0} 和 {1} 子层级顺序不匹配！".format(source_group, target_group))
                    return [source_group_short_name, target_group_short_name]
                print 'aaaaaa'
                length = len(source_children)
                for index in range(length):
                    feedback = self.match_group_hierarchy(source_children[index], target_children[index], source_group, target_group)
                    if feedback:
                        return feedback
                return False
        else:
            return [self.get_short_name(source_group), self.get_short_name(target_group)]

    def remove_uncheck_group(self, pass_group, source_children, target_children, source_short_children, target_short_children):
        for i in source_children:
            if pass_group in i:
                source_children.remove(i)
        for i in target_children:
            if pass_group in i:
                target_children.remove(i)
        for i in source_short_children:
            if pass_group in i:
                source_short_children.remove(i)
        for i in target_short_children:
            if pass_group in i:
                target_short_children.remove(i)

    def get_children_with_short(self, parent):
        short_name_children = []
        children = cmds.listRelatives(parent, f=0, c=1)
        if not children:
            return short_name_children
        for c in children:
            if cmds.getAttr('%s.intermediateObject' % c):
                print c, cmds.getAttr('%s.intermediateObject' % c)
                children.remove(c)
        for c in children:
            if ':' in c:
                c = c.split(":")[-1]
            short_name_children.append(c)
        return short_name_children

    def check_children_sequence(self, source_children, target_children):
        if source_children != target_children:
            return False
        else:
            return True

    def get_type_nodes(self, node, nodes_lib=[], type="mesh"):
        for subnode in cmds.listRelatives(node, f=True, c=1):
            if cmds.nodeType(subnode) == "mesh":
                nodes_lib.append(subnode)
            if cmds.listRelatives(subnode, f=True, c=1):
                self.get_type_nodes(subnode, nodes_lib, type)

    def rig_mod_version_check(self, group):
        mesh_nodes = []
        error_nodes = []
        self.get_type_nodes(group, mesh_nodes)
        for node in mesh_nodes:
            try:
                node_ver = cmds.getAttr(node + ".modVer")
                if node_ver != self.latest_version:
                    error_nodes.append(cmds.ls(node)[0])
            except:
                pass
        return error_nodes

    def check(self):
        print 'aaaaa'
        self.init_file()
        source_grp = "|Root_Grp|mod_grp"
        if not cmds.objExists(source_grp):
            return u'Error:%s\n不存在绑定规则的这个组' % source_grp

        # rig中的mesh节点版本检查
        version_check_result = self.rig_mod_version_check(source_grp)
        if version_check_result:
            return u'Error:%s\n 查询到这些模型不是最新mod版本(%s)，请更新!' % (version_check_result, self.latest_version)

        result_proc = None
        ref_file = self.import_mod_ref_file()
        if ref_file:
            namespace = cmds.file(ref_file, q=1, namespace=1)
            target_grp = "%s:mod_grp" % namespace
            if cmds.objExists(source_grp) and cmds.objExists(target_grp):
                result_proc = self.match_group_hierarchy(source_grp, target_grp)
            else:
                return u'Error:没找到可匹配的节点%s\n' % target_grp

        else:
            return u'Error:未找到匹配的abc文件\n'

        if result_proc:
            result_log = u'Error:%s\n' % result_proc
        else:
            result_log = u'Succeed:没有问题\n'
            cmds.file(ref_file, rr=1)

        return result_log

    def fix(self):
        pass

